package com.qianniu.napi.admin.web;

import akka.actor.ActorRef;
import akka.actor.Props;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.google.common.base.Strings;
import com.jpay.ext.kit.StrKit;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.jsmodel.UserDetail;
import com.qianniu.napi.admin.entity.penum.ActgxType;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.admin.service.akka.AkkaServer;
import com.qianniu.napi.admin.service.akka.UserActor;
import com.qianniu.napi.common.config.Constants;
import com.qianniu.napi.common.util.ObjectUtil;
import nl.bitwalker.useragentutils.UserAgent;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * <p>
 * </p>
 *
 * @author chenxuebin
 * @since 2018-11-26
 */
@RestController
public class UserstatController {

    private static final Logger logger = LoggerFactory.getLogger(UserstatController.class);

    @Autowired
    private IUserstatService userstatService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IUsermpService usermpService;
    @Autowired
    private IActgxService actgxService;
    @Autowired
    private IConfigService configService;
    @Autowired
    private RedissonClient redis;

    @RequestMapping("/api/userstat/list")
    @ResponseBody
    public Jinfo list(@RequestParam(value = "status", required = false) String status,
                      @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
                      @RequestParam(value = "pageSize", required = false) Integer pageSize,
                      HttpServletRequest req) {
        Jinfo info = new Jinfo();
        if (pageSize == null) pageSize = 10;
        Page page = new Page(pageIndex, pageSize);
        page = userstatService.selectPage(page, new EntityWrapper<Userstat>()
                .eq("uid", ObjectUtil.getUid())
                .eq("state", 1));
        info.setInfo(page.getRecords());
        return info;
    }

    @RequestMapping("/api/userstat/add")
    @ResponseBody
    public Jinfo userstatAdd(@Valid Userstat userstat,
                             BindingResult bindingResult, HttpServletRequest req) {
        Jinfo info = new Jinfo();
        // 字段校验
        if (bindingResult.hasErrors()) {
            logger.debug("There are errors! {}", bindingResult);
            info.setMsg("There are errors! " + bindingResult);
            info.setCode(400);
            return info;
        }
        userstat.setCreatetime(new Date());
        userstat.setMid(ObjectUtil.getMid());
        userstat.setMpid(ObjectUtil.getMpid());
        userstat.setUid(ObjectUtil.getUid());
        userstat.insert();
        return info;
    }

    @RequestMapping("/api/userstat/modify")
    @ResponseBody
    public Jinfo userstatUpdate(
            Userstat userstat) {
        Jinfo info = new Jinfo();
        userstat.setModifytime(new Date());
        userstat.updateById();
        return info;
    }

//    名片详情
//    guid：被访问者guid
    @RequestMapping("/api/userstat/detail")
    @ResponseBody
    public Jinfo getUserstatDetail(HttpServletRequest req,
                                   @RequestParam(value = "vuid", required = false) Integer vuid,
                                   @RequestParam(value = "guid", required = false) String guid,
                                   @RequestParam(value = "ori", required = false) String ori) {

        Jinfo info = new Jinfo();
        logger.debug("=========api/userstat/detail vuid=" + vuid);
        logger.debug("=========api/userstat/detail ori=" + ori);
        logger.debug("=========api/userstat/detail guid=" + guid);
        Long uid = ObjectUtil.getUid();

        Wrapper<Usermp> entity = new EntityWrapper<Usermp>().setSqlSelect("id,name,company,phone,duty,avatar_pic avatarPic,address,gongkai,email,weixin,mpimg,mpclass,mptype,hasmp,gids,gphotos,vedio,photo,audio,signature,skill,resource,guid");
        String rkey = Constants.REDIS_USERSTAT_DETAIL;

        if (!Strings.isNullOrEmpty(guid)) {
            entity.eq("guid", guid);
        } else if (ObjectUtil.getUid() != null && ObjectUtil.getUid() > 0) {
            entity.eq("id", ObjectUtil.getUid());
        }

        if (!Strings.isNullOrEmpty(guid)) {
            rkey += guid;
        } else if (ObjectUtil.getUid() != null && ObjectUtil.getUid() > 0) {
            rkey += ObjectUtil.getUid();
        }

        Usermp user = null;
        if(!Strings.isNullOrEmpty(rkey)) {
            RBucket<Usermp> bucket = redis.getBucket(rkey);
            logger.debug("========rkey=" + rkey);
            if (bucket.isExists() && bucket.get() != null) {
                logger.debug("========rkey value=" + bucket.get());
                user = bucket.get();
            }else{
                user= usermpService.selectOne(entity);
            }
        }else{
            user= usermpService.selectOne(entity);
        }
        logger.debug("=========AkkaServer user.getId()=" + user.getId());
        logger.debug("=========AkkaServer uid=" + uid);

        if (uid!=null&& user.getId().longValue() != uid.longValue()&& ObjectUtil.getUid() != null) {
            String ip = ObjectUtil.getIP(req);
            if (StrKit.isBlank(ip)) {
                ip = "127.0.0.1";
            }
            String ua = req.getHeader("User-Agent");
            UserAgent userAgent = UserAgent.parseUserAgentString(req.getHeader("User-Agent"));
            String os = userAgent.getOperatingSystem().toString();
            String msg = Constants.AKKA_MSG_VISIT_USERSTAT + "@" +uid+"##"+ user.getId()+"##"+  ObjectUtil.getMid()+"##"+ ObjectUtil.getMpid()+"##"+  ActgxType.visit.getVal()+"##"+ip+"##"+os;
            logger.debug("=========AkkaServer msg=" + msg);

            AkkaServer.system.actorOf(Props.create(UserActor.class)).tell(msg, ActorRef.noSender());
//            this.recordAct(uid, user.getId(), ObjectUtil.getMid(), ObjectUtil.getMpid(), ActgxType.visit.getVal(), req);
        }

        UserDetail map = new UserDetail();

        map.setUsermp(user);
        logger.debug("=========getUserstatDetail user=" + JSON.toJSONString(user));

        Userstat ustat = userstatService.selectOne(new EntityWrapper<Userstat>().setSqlSelect("id,uid,access,visit,gfav,ufav,zuan,shuo,dongtai,renqi,kehu").eq("uid", user.getId()));
        map.setUstat(ustat);

        logger.debug("=========getUserstatDetail ustat= " + JSON.toJSONString(user));
        Boolean shoucang = false;
        if (!Strings.isNullOrEmpty(guid)) {
            Wrapper<Actgx> aentity = new EntityWrapper<Actgx>().setSqlSelect("id,uid,vuid,type").eq("uid", uid).eq("guid", guid).eq("type", 3);
            Actgx actgx = actgxService.selectOne(aentity);
            if(actgx!=null)shoucang=true;
        }
        map.setShoucang(shoucang);

        info.setInfo(map);

        return info;
    }

    @RequestMapping("/api/nmp/guangchang")
    @ResponseBody
    public Jinfo guangchang(@RequestParam(value = "type", required = false) int type,
                            @RequestParam(value = "souso", required = false) String souso,
                            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
                            @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        Jinfo info = new Jinfo();
        String paixu = "modifytime";
        if (pageSize == null) pageSize = 10;
        if (pageIndex == null) pageIndex = 1;
        Long mid = ObjectUtil.getMid();

        Page page = new Page(pageIndex, pageSize);
        Wrapper<Usermp> entity = new EntityWrapper<Usermp>().setSqlSelect("id,name,company,gs,phone,duty,hasmp,avatar_pic avatarPic,weixin,hasmp,gongkai,guid")
                .eq("beiso", 1).eq("state", 1).eq("mid", mid).eq("mpid", ObjectUtil.getMpid());
        if (!Strings.isNullOrEmpty(souso)) {
            entity.like("name", souso).or().like("company", souso).or().like("phone", souso).or().like("duty", souso);
        }
        if (type > 2) paixu = "modifytime";

        entity.orderBy(paixu, false);
        page = usermpService.selectPage(page, entity);
        info.setInfo(page.getRecords());
        return info;
    }

    @RequestMapping("/api/nmp/mpjia")
    @ResponseBody
    public Jinfo mpjia(@RequestParam(value = "souso", required = false) String souso,
                       @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
                       @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        Jinfo info = new Jinfo();

        if (pageSize == null) pageSize = 10;
        if (pageIndex == null) pageIndex = 1;

        Long mpid = ObjectUtil.getMpid();
        Long uid = ObjectUtil.getUid();
        Map map = new HashMap<String, Object>();

        if (pageIndex == 1) {
            Userstat ustat = userstatService.selectOne(new EntityWrapper<Userstat>().setSqlSelect("id,uid,access,visit,accessc,visitc,gfav,ufav,zuan,shuo,dongtai,renqi,kehu").eq("uid", uid));
            map.put("ustat", ustat);
        }

        Page page = new Page(pageIndex, pageSize);
        Wrapper<Actgx> aentity = new EntityWrapper<Actgx>().setSqlSelect("id,uid,vuid,type,status,guid,group_type,name,avatar,phone,qqcount,dongtai,company,gs,fenlei,renqi,createtime")
                .eq("uid", uid).eq("mpid", mpid).eq("isfirst", 1)
                .eq("type", 3);//首次收藏点赞
        if (!Strings.isNullOrEmpty(souso)) aentity.andNew().like("name", souso).or().like("phone", souso);// 一期只支持姓名搜索和手机号
        page = actgxService.selectPage(page, aentity);

        map.put("list", page.getRecords());
        info.setInfo(map);
        return info;
    }

    @RequestMapping("/api/nmp/hangyes")
    @ResponseBody
    public Jinfo hangyes() {

        Jinfo info = new Jinfo();
        Map map = new HashMap<String, Object>();
        Wrapper<Config> entity = new EntityWrapper<Config>().setSqlSelect("id,name").eq("type", "hangye").eq("pid", 2400).eq("level", 2);
        List<Config> list = configService.selectList(entity);
        map.put("list", list);
        info.setInfo(map);
        return info;
    }

    @RequestMapping("/api/nmp/addhangye")
    @ResponseBody
    public Jinfo addhangye(@RequestParam(value = "hangye", required = false) String hangye) {

        Jinfo info = new Jinfo();
        Config config = new Config();
        config.setType("hangye");
        config.setName(hangye);
        config.setUid(ObjectUtil.getUid());
        config.setMid(ObjectUtil.getMid());
        config.setIsSystem(-1);
        config.setState(1);
        try {
            config.setCode(PinyinHelper.convertToPinyinString(hangye, "", PinyinFormat.WITHOUT_TONE));
        } catch (Exception e) {
        }
        config.insert();
        info.setInfo(config);
        return info;
    }

    @RequestMapping("/api/nmp/visit")
    @ResponseBody
    public Jinfo myvisit(@RequestParam(value = "type", required = false) String type,
                         @RequestParam(value = "souso", required = false) String souso,
                         @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
                         @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        Jinfo info = new Jinfo();

        if (pageSize == null) pageSize = 10;
        if (pageIndex == null) pageIndex = 1;

        Long mid = ObjectUtil.getMid();
        Long uid = ObjectUtil.getUid();

        Page page = new Page(pageIndex, pageSize);
//        Wrapper<Actgx> aentity = new EntityWrapper<Actgx>().setSqlSelect("id,uid,vuid,count(distinct vuid),type,status,group_type,name,avatar,phone,qqcount,visitday,dongtai,company,gs,fenlei,createtime,guid")
        Wrapper<Actgx> aentity = new EntityWrapper<Actgx>().setSqlSelect("vuid,id,uid,count(vuid),type,group_type,name,avatar,phone,qqcount,dongtai,company,gs,guid")
                .eq("uid", uid).eq("mid", mid).eq("type", type).groupBy("vuid");
        if (!Strings.isNullOrEmpty(souso)) aentity.like("name", souso).or().like("phone", souso);// 一期只支持姓名搜索和手机号
        aentity.orderBy("id", false);
        page = actgxService.selectPage(page, aentity);

        info.setInfo(page.getRecords());
        return info;
    }

    @RequestMapping("/api/userstat/uinfo")
    @ResponseBody
    public Jinfo uinfo(@RequestParam(value = "muid", required = false) String muid) {

        Jinfo info = new Jinfo();
        Long uid = ObjectUtil.getUid();

        Wrapper<Usermp> entity = new EntityWrapper<Usermp>()
                .setSqlSelect("id,name,company,gs,phone,telphone,duty,skill,hangye,hangyeid,address,addr,signature,avatar_pic avatarPic,depart,gphotos,vedio,audio,email,latitude,longitude,mpimg,mpclass,mptype,qq,weibo,weixin,weixinimg,beiso,gongkai,guid")
                .eq("id", uid);
        Usermp user = usermpService.selectOne(entity);
        // 读取副名片
        if (!Strings.isNullOrEmpty(muid)) {

        }

        info.setInfo(user);
        return info;
    }

    @RequestMapping("/api/nmp/addmp")
    @ResponseBody
    public Jinfo myvisit(Usermp user) {

        Jinfo info = new Jinfo();
        try {
            Long uid = ObjectUtil.getUid();
            user.setHasmp(1);
            user.setId(uid);
            user.insertOrUpdate();

            String rkey = Constants.REDIS_USERSTAT_DETAIL+user.getId();
            String rkeyg = Constants.REDIS_USERSTAT_DETAIL+user.getGuid();
            RBucket<Usermp> bucket = redis.getBucket(rkey);
            RBucket<Usermp> rkeygBucket = redis.getBucket(rkeyg);

            if(bucket.isExists())bucket.delete();
            if(rkeygBucket.isExists())rkeygBucket.delete();

        } catch (Exception e) {
            logger.error("==========user.insertOrUpdate", e);
        }
        return info;
    }

    @RequestMapping("/api/nmp/dianzan")
    @ResponseBody
    public Jinfo dianzan(@RequestParam(value = "guid", required = false) String guid, @RequestParam(value = "type", required = false) Integer type, HttpServletRequest req) {

        Jinfo info = new Jinfo();

//        String hangye="保险业、采矿、能源、餐饮、宾馆、电讯业、房地产、服务、服装业、公益组织、广告业、航空航天、化学、健康、保健、建筑业、教育、培训、计算机、金属冶炼、警察、消防、军人、会计、美容、媒体、出版、木材、造纸、零售、批发、农业、旅游业、司法、律师、司机、体育运动、学术研究、演艺、医疗服务、艺术、设计、银行、金融、因特网、音乐舞蹈、邮政快递、运输业、政府机关、机械制造、咨询";
        Wrapper<Usermp> entity = new EntityWrapper<Usermp>().setSqlSelect("id,name,company,gs,phone,duty,hasmp,gongkai,avatar_pic avatarPic,nick_name nickName, weixin,photo,guid")
                .eq("state", 1).eq("guid", guid);
        Usermp user = usermpService.selectOne(entity);

        Long mid = ObjectUtil.getMid();
        Long mpid = ObjectUtil.getMpid();
        Long uid = ObjectUtil.getUid();
        if(uid==null||user==null) return info;

        Actgx act = new Actgx();
        act.setUid(uid);
        act.setVuid(user.getId());
        act.setGuid(guid);
        act.setHangye(user.getHangye());

        act.setMid(mid);
        act.setMpid(ObjectUtil.getMpid());
        act.setCreatetime(new Date());

        act.setType(type);
        String ip = ObjectUtil.getIP(req);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        act.setIp(ip);
        String ua = req.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(req.getHeader("User-Agent"));
        String os = userAgent.getOperatingSystem().toString();
        act.setTerminal(os);
        if(uid.longValue()==user.getId().longValue())return info;

        String msg = Constants.AKKA_MSG_VISIT_USERSTAT + "@" +uid+"##"+ user.getId()+"##"+  ObjectUtil.getMid()+"##"+ ObjectUtil.getMpid()+"##"+  ActgxType.dianzan.getVal()+"##"+ip+"##"+os;
        logger.debug("=========AkkaServer msg=" + msg);
        AkkaServer.system.actorOf(Props.create(UserActor.class)).tell(msg, ActorRef.noSender());

        return info;
    }

    // 记录当前用户的行为
    public void recordAct(Long uid, Long vuid, Long mid, Long mpid, int type, HttpServletRequest req) {
        logger.debug("=========start to recordAct");

        Actgx act = new Actgx();
        act.setUid(uid);
        act.setVuid(vuid);

        act.setMid(mid);
        act.setQqcount(0);
        act.setMpid(ObjectUtil.getMpid());
        act.setCreatetime(new Date());

        act.setType(type);
        String ip = ObjectUtil.getIP(req);
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }
        act.setIp(ip);
        String ua = req.getHeader("User-Agent");
        UserAgent userAgent = UserAgent.parseUserAgentString(req.getHeader("User-Agent"));
        String os = userAgent.getOperatingSystem().toString();
        act.setTerminal(os);

        Wrapper<Usermp> entity = new EntityWrapper<Usermp>().setSqlSelect("id,name,company,gs,phone,duty,hasmp,gongkai,avatar_pic avatarPic,nick_name nickName, weixin,photo,guid")
                .eq("state", 1).eq("id", vuid);

        Usermp user = usermpService.selectOne(entity);
        act.setName(Strings.isNullOrEmpty(user.getName()) ? user.getNickName() : user.getName());
        act.setAvatar(Strings.isNullOrEmpty(user.getPhoto()) ? user.getAvatarPic() : user.getPhoto());
        act.setPhone(user.getPhone());
        act.setCompany(user.getCompany());
        act.setGs(user.getGs());
        act.setGuid(user.getGuid());
        act.setHangye(user.getHangye());

        act.insert();

        Wrapper<Userstat> entity2 = new EntityWrapper<Userstat>().eq("uid", vuid);
        Userstat ustat = userstatService.selectOne(entity2);
        logger.debug("=========ustat="+JSON.toJSONString(ustat));

        if (ustat == null) {
            this.initUstat(vuid, user.getGuid(), mid, mpid, type);
        } else {
            this.updateUstat(ustat, type);
        }
    }

    // 被访问用户的行为数据统计
    private Userstat initUstat(Long vuid, String guid, Long mid, Long mpid, int type) {

        Userstat ustat = new Userstat();
        ustat.setUid(vuid);
        ustat.setGuid(guid);
        ustat.setMid(mid);
        ustat.setMpid(mpid);

        ustat.setAccess(type == ActgxType.access.getVal() ? 1 : 0);
        ustat.setVisit(type == ActgxType.visit.getVal() ? 1 : 0);

        ustat.setAccessc(type == ActgxType.access.getVal() ? 1 : 0);
        ustat.setVisitc(type == ActgxType.visit.getVal() ? 1 : 0);

        ustat.setGfav(type == ActgxType.gfav.getVal() ? 1 : 0);
        ustat.setUfav(type == ActgxType.ufav.getVal() ? 1 : 0);
        ustat.setZuan(type == ActgxType.dianzan.getVal() ? 1 : 0);

        ustat.setKehu(type == ActgxType.addkehu.getVal() ? 1 : 0);

        ustat.setKehu(type == ActgxType.share.getVal() ? 1 : 0);
        ustat.setShare(type == ActgxType.share.getVal() ? 1 : 0);
        ustat.setCall(type == ActgxType.call.getVal() ? 1 : 0);

        ustat.setShuo(0);
        ustat.setDongtai(0);
        ustat.setKehu(0);
        ustat.setRenqi(1);
        ustat.setState(1);
        ustat.setIsHuoyue(1);
        ustat.setLastvtime(new Date());
        ustat.setCreatetime(new Date());

        ustat.insert();
        return ustat;
    }

    private Userstat updateUstat(Userstat ustat, int type) {
        logger.debug("=========updateUstat type="+type);
        logger.debug("=========updateUstat ustat="+JSON.toJSONString(ustat));

        if (type == ActgxType.access.getVal())
            ustat.setAccess(ustat.getAccess() + 1);
        else if (type == ActgxType.visit.getVal())
            ustat.setVisit(ustat.getVisit() + 1);
        else if (type == ActgxType.gfav.getVal())
            ustat.setGfav(ustat.getGfav() + 1);
        else if (type == ActgxType.ufav.getVal())
            ustat.setUfav(ustat.getUfav() + 1);
        else if (type == ActgxType.dianzan.getVal())
            ustat.setZuan(ustat.getZuan() + 1);
        else if (type == ActgxType.addkehu.getVal())
            ustat.setKehu(ustat.getKehu() + 1);
        else if (type == ActgxType.share.getVal())
            ustat.setShare(ustat.getShare() + 1);
        else if (type == ActgxType.call.getVal())
            ustat.setCall(ustat.getCall() + 1);

        logger.debug("=========updateUstat 111");
        ustat.setRenqi(ustat.getRenqi() + 1);
        logger.debug("=========updateUstat 222");

        ustat.setModifytime(new Date());
        logger.debug("=========updateUstat 333");
        userstatService.update(ustat,new EntityWrapper<Userstat>().eq("id",ustat.getId()));

        logger.debug("=========updateUstat updateById ok");
        return ustat;
    }

}
